import random, string
import hashlib
import time
from pypinyin import pinyin, Style
from django_redis import get_redis_connection
from rest_framework import viewsets
from .Authentication import *

from mysqldb.models import AllinpayAuthViews


def hash_md5(x):
    """MD5加密"""
    return hashlib.md5(x.encode("utf-8")).hexdigest()


def hash_name(x):
    """姓名加密"""
    return f"{x[0]}*{x[-1]}"


def hash_time(x):
    """时间戳转datetime"""
    return datetime.fromtimestamp(x)


def hash_stamp(x):
    """datetime转时间戳"""
    return int(time.mktime(x))


def hash_time_stamp(x):
    """时间戳转str"""
    return str(time.time())


def hash_time_stamp_md5(x):
    """时间戳转str"""
    return hashlib.md5(str(time.time()).encode("utf-8")).hexdigest()


# def hash_time_stamp_md5_2(x):
#     """时间戳转str"""
def has_Random(l=6):
    """返回随机数"""
    s = ""
    for i in range(l):
        s += str(random.choice(range(9)))
    return s


def has_PassWord(len=6):
    """返回随机密码"""
    # work = string.ascii_lowercase + string.ascii_uppercase + string.digits + string.punctuation
    work = string.ascii_letters + string.digits + string.punctuation
    chosen = random.sample(work, len)
    return "".join(chosen)


def has_PassWordB(len=6, level=3):
    """
    len=6 长度
    level=1 数字，2+字母，3+符号
    """
    work = string.digits
    if level > 1:
        work += string.ascii_letters
    if level > 2:
        work += string.punctuation
    chosen = random.sample(work, len)
    return "".join(chosen)


def has_Reqsn_Callme():
    """创建呼叫订单号"""
    s = "CALL"
    s += time.strftime("%Y%m%d%H%M%S", time.localtime())
    s += has_PassWordB(6, 2)
    return s.upper()


def has_Reqsn_Post():
    """创建兑换订单号"""
    s = "POST"
    s += time.strftime("%Y%m%d%H%M%S", time.localtime())
    s += has_PassWordB(6, 2)
    return s.upper()


def has_Reqsn_Anyone(t):
    """创建单号"""
    s = f"{t}"
    s += time.strftime("%Y%m%d%H%M%S", time.localtime())
    s += has_PassWordB(6, 2)
    return s.upper()


def py_str(x=""):
    """返回简称"""
    vstr = ""
    obj = pinyin(x, style=Style.FIRST_LETTER)
    for i in obj:
        vstr += i[0]
    return vstr


def redis_key_set(key, value=1, t=0):
    """写入缓存同步标志"""
    return
    rds = get_redis_connection("syncAlert")
    rds.set(key, value)
    res = rds.expire(key, t) if t else 0
    return rds.strlen(key)


def redis_list_append(key, db, t=0):
    """插入数据到右边(同步消息通知)"""
    rds = get_redis_connection("syncAlert")
    rds.rpush(key, str(db))
    res = rds.expire(key, t) if t else 0
    return rds.llen(key)


def factors(n):
    """求因数列表"""
    return [i for i in range(1, n + 1) if n % i == 0]


def filter_views(obj):
    """筛选视图权限列表"""
    for sess in list(obj.keys()):
        if not isinstance(obj[sess], type):
            continue
        if issubclass(obj[sess], viewsets.ModelViewSet):
            # print(obj[sess].__name__, obj[sess].__title__, obj[sess].http_method_names)
            # print(obj[sess].__name__,obj[sess].authentication_classes,obj[sess].permission_classes)
            if not obj[sess].authentication_classes:
                # print(
                #     obj[sess].__name__,
                #     str(obj[sess].http_method_names),
                #     obj[sess].__title__,
                # )
                continue
            # 判断员工视图类型
            Staff = 0
            if MyJWTAuthentication in obj[sess].authentication_classes:
                Staff += 1
            if (
                WeChatJWTAuthentication in obj[sess].authentication_classes
                or BarJWTAuthentication in obj[sess].authentication_classes
            ):
                Staff += 2
            # if XboxJWTAuthentication in obj[sess].authentication_classes:
            #     Staff += 8
            # if RboxJWTAuthentication in obj[sess].authentication_classes:
            #     Staff += 16
            # print(obj[sess].authentication_classes)
            # print(Staff, bin(Staff))

            # 写入数据库
            for act in obj[sess].http_method_names:
                if hasattr(obj[sess], "__info__"):
                    info = obj[sess].__info__.get(act)
                else:
                    info = obj[sess].__title__
                if hasattr(obj[sess], "__group__"):
                    model = obj[sess].__group__
                    group = obj[sess].__title__
                else:
                    model = "默认视图"
                    group = "默认视图"
                # print(obj[sess].__name__, act.upper())
                AllinpayAuthViews.objects.update_or_create(
                    defaults={
                        "info": info,
                        # "model": model,
                        "group": f"{model}:{group}",
                        "staff": int(Staff),
                    },
                    name=obj[sess].__name__,
                    act=act.upper(),
                )


# ================Start RC4=======================================
def KSA(key):
    key_length = len(key)
    # 初始化S盒
    S = list(range(256))
    j = 0
    for i in range(256):
        j = (j + S[i] + key[i % key_length]) % 256
        # 交换S[i]和S[j]
        S[i], S[j] = S[j], S[i]
    return S


def PRGA(S):
    i = 0
    j = 0
    while True:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        # 交换S[i]和S[j]
        S[i], S[j] = S[j], S[i]
        K = S[(S[i] + S[j]) % 256]
        yield K


def RC4(key="found".encode("utf-8")):
    # 加密函数，返回加密后的字节流
    def encrypt(data):
        data_length = len(data)
        keystream = PRGA(KSA(key))
        res = []
        for i in range(data_length):
            res.append(next(keystream) ^ data[i])
        return bytes(res)

    # 解密函数，返回解密后的字节流
    def decrypt(data):
        return encrypt(data)

    return encrypt, decrypt


# # 示例：
# key = b'secret_key'
# encrypt_func, decrypt_func = RC4(key)
# data_to_encrypt=b'Hello World'
# encrypted_data=encrypt_func(data_to_encrypt)
# print('Encrypted Data:', encrypted_data)
# decrypted_data=decrypt_func(encrypted_data)
# print('Decrypted Data:', decrypted_data)
# import base64
# s = '人生苦短，我学python！'
# # 加密
# b = base64.b64encode(s.encode('utf-8'))
# print(b)
# # 解密
# c = base64.b64decode(b).decode('utf-8')
# print(c)
# ================END RC4=======================================
